package com.test.auth_db_auto.auth_sms;

import com.test.auth_db_auto.support.BootSecurityProperties;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.Assert;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @ Author: .Mr
 * @ ClassName SmsCodeAuthenticationFilter
 * @ Description TODO
 * @ date 2022/1/5 9:40
 * @ Version 1.0
 * 对短信登录的请求进行拦截，获取相应的数进行处理
 */
public class SmsCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    //请求中，参数为mobile
    private static final String BOOT_FORM_MOBILE_KEY="mobile";
    //密码的key
    private static final String BOOT_FORM_PASSWORD_KEY="m_password";
    //检验用户的唯一key
    private static final String BOOT_FORM_CHECK_KEY="examine_key";

    private String mobileParameter=BOOT_FORM_MOBILE_KEY;
    private String passwordParameter=BOOT_FORM_PASSWORD_KEY;
    private String checkKeyParameter=BOOT_FORM_CHECK_KEY;

    //是否只处理post的请求
    private boolean postOnly=true;

    protected SmsCodeAuthenticationFilter(String path) {
        super(new AntPathRequestMatcher(path,"POST"));
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {

        if(postOnly&& !request.getMethod().equalsIgnoreCase("POST")){
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }
        String mobile =obtainMobile(request);
        String password=obtainPassword(request);
        String check=obtainCheck(request);

        SmsCodeAuthenticationToken authRequest = new SmsCodeAuthenticationToken(mobile==null?"":mobile.trim(),password==null?"":password.trim(),check==null?"":check.trim());

        setDetails(request,authRequest);

        return this.getAuthenticationManager().authenticate(authRequest);
    }

    /**
     * 获取手机号
     * */
    private String obtainMobile(HttpServletRequest request){return  request.getParameter(mobileParameter);}
    /**
     * 获取用户设置的密码
     * */
    private String obtainPassword(HttpServletRequest request){return request.getParameter(passwordParameter);}
    /**
     * 获取用户的唯一标识
     * */
    private String obtainCheck(HttpServletRequest request){return request.getParameter(checkKeyParameter);}
    /**
     * Provided so that subclasses may configure what is put into the authentication
     * request's details property.
     *
     * @param request that an authentication request is being created for
     * @param authRequest the authentication request object that should have its details
     * set
     */
    private void setDetails(HttpServletRequest request,SmsCodeAuthenticationToken authRequest){
        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
    }
    /**
     * 设置将用于从登录中获取用户名的参数名称
     * request.
     * @param usernameParameter the parameter name. Defaults to "username".
     * */
    public void setMobileParameter(String usernameParameter){
        Assert.hasText(usernameParameter,"Username parameter must bot by empty or null");
        this.mobileParameter=usernameParameter;
    }
}
